package com.ruoyi.service.project.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.enums.YesNoEnum;
import com.ruoyi.common.core.utils.sql.SqlUtil;
import com.ruoyi.service.project.entity.ProjectEntity;
import com.ruoyi.service.project.enums.ProjectStatusEnum;
import com.ruoyi.service.project.mapper.ProjectMapper;
import com.ruoyi.service.project.query.InvoiceQuery;
import com.ruoyi.service.project.query.ProjectQueryForDemander;
import com.ruoyi.service.project.query.ProjectQueryForLabor;
import com.ruoyi.service.project.query.ProjectQueryForPlatform;
import com.ruoyi.service.project.service.ProjectService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 项目信息表 服务实现类
 * </p>
 *
 * @author Zane
 * @since 2025-10-11
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, ProjectEntity>
    implements ProjectService {


  @Override
  public List<ProjectEntity> listForDemander(ProjectQueryForDemander query, Long companyId) {
    final LambdaQueryWrapper<ProjectEntity> queryWrapper = effectQuery().eq(ProjectEntity::getComId,
        companyId).orderByDesc(ProjectEntity::getId);
    if (StrUtil.isNotBlank(query.getProjectName())) {
      queryWrapper.like(ProjectEntity::getProjectName, query.getProjectName());
    }
    return list(queryWrapper);
  }

  @Override
  public List<ProjectEntity> listForLabor(ProjectQueryForLabor query) {
    return this.baseMapper.listForLabor(query);
  }

  @Override
  public List<ProjectEntity> listForPlatform(ProjectQueryForPlatform query) {
    final LambdaQueryWrapper<ProjectEntity> queryWrapper = effectQuery()
        .ge(ProjectEntity::getStatus, ProjectStatusEnum.PUBLISH.getCode())
        .orderByDesc(ProjectEntity::getId);
    if (StrUtil.isNotBlank(query.getProjectName())) {
      queryWrapper.like(ProjectEntity::getProjectName, query.getProjectName());
    }
    return list(queryWrapper);
  }

  @Override
  public List<ProjectEntity> publishAndNeedStart() {
    return list(effectQuery().eq(ProjectEntity::getStatus, ProjectStatusEnum.PUBLISH.getCode())
        .le(ProjectEntity::getProjectStart, LocalDateTime.now()));
  }

  @Override
  public List<ProjectEntity> delayNotifyList() {
    //5分钟内需要发送通知的所有项目
    return list(effectQuery().in(ProjectEntity::getStatus, ProjectStatusEnum.getNotifyStatusList())
        //结束时间已到
        .le(ProjectEntity::getProjectEnd, LocalDateTime.now())
        //5分钟之内结束的数据
        .ge(ProjectEntity::getProjectEnd, LocalDateTime.now().minusMinutes(5))
    );
  }

  @Override
  public Long countForCooperation(Long userId) {
    return count(effectQuery()
        .eq(ProjectEntity::getCreateBy, userId));
  }

  @Override
  public Long getDemanderVerifyCount(Long userId) {
    return count(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.VERIFYING.getCode())
        .eq(ProjectEntity::getCreateBy, userId));
  }

  @Override
  public Long getDemanderExecutionCount(Long userId) {
    return count(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.ON_EXECUTION.getCode())
        .eq(ProjectEntity::getCreateBy, userId));
  }

  @Override
  public Long getProjectCount() {
    return count(effectQuery());
  }

  @Override
  public Long getExecutionCount() {
    return count(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.ON_EXECUTION.getCode()));
  }

  @Override
  public List<ProjectEntity> listForInvoice(InvoiceQuery query) {
    return list(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.getSettleStatusList())
        .eq(ProjectEntity::getInvoiceFlag, YesNoEnum.NO.getCode())
    );
  }

  @Override
  public List<ProjectEntity> demanderListForCooperation(ProjectQueryForDemander projectQuery,
      Long userId) {
    return list(effectQuery().eq(ProjectEntity::getCreateBy, userId));
  }

  @Override
  public List<ProjectEntity> demanderListForVery(ProjectQueryForDemander projectQuery,
      Long userId) {
    return list(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.VERIFYING.getCode())
        .eq(ProjectEntity::getCreateBy, userId));
  }

  @Override
  public List<ProjectEntity> demanderListForExecution(ProjectQueryForDemander projectQuery,
      Long userId) {
    return list(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.ON_EXECUTION.getCode())
        .eq(ProjectEntity::getCreateBy, userId));
  }

  @Override
  public Long projectDemanderSuddenCount(Long userId) {
    // 异常项目数量
//    final QueryWrapper<String> subQuery = new QueryWrapper<String>()
//        .select("project_id")
//        .eq("project_creator", userId)
//        .eq("delete_flag", YesNoEnum.NO.getCode());
    final String subSql = SqlUtil.formatSql(
        " select project_id from t_project_sudden where project_creator='{}' and delete_flag='0' ",
        userId);
    return count(effectQuery()
        .eq(ProjectEntity::getCreateBy, userId)
        .inSql(ProjectEntity::getId, subSql)
    );
  }

  @Override
  public List<ProjectEntity> demanderListForSudden(ProjectQueryForDemander projectQuery,
      Long userId) {
//    final QueryWrapper<String> subQuery = new QueryWrapper<String>()
//        .select("project_id")
//        .eq("project_creator", userId)
//        .eq("delete_flag", YesNoEnum.NO.getCode());
    final String subSql = SqlUtil.formatSql(
        " select project_id from t_project_sudden where project_creator='{}' and delete_flag='0' ",
        userId);
    return list(effectQuery()
        .eq(ProjectEntity::getCreateBy, userId)
        .inSql(ProjectEntity::getId, subSql)
    );
  }

  @Override
  public Map<String, ProjectEntity> selectMapByIds(List<String> projectIds) {
    if (CollUtil.isEmpty(projectIds)) {
      return new HashMap<>();
    }
    return Optional.ofNullable(listByIds(projectIds)).orElseGet(ArrayList::new).stream()
        .collect(Collectors.toMap(ProjectEntity::getId, v -> v, (v1, v2) -> v1));
  }

  @Override
  public List<ProjectEntity> laborListForFinish(ProjectQueryForDemander projectQuery, Long userId) {
    final String subSql = SqlUtil.formatSql(" select project_id from t_project_labor "
        + "where labor_Id='{}' and status='1' and work_finish_flag='1' ", userId);
    return list(effectQuery()
        .inSql(ProjectEntity::getId, subSql));
  }

  @Override
  public List<ProjectEntity> laborListForApply(ProjectQueryForDemander projectQuery, Long userId) {
    final String subSql = SqlUtil.formatSql(" select project_id from t_project_labor "
        + "where labor_Id='{}'  ", userId);
    return list(effectQuery()
        .eq(ProjectEntity::getStatus, ProjectStatusEnum.PUBLISH.getCode())
        .inSql(ProjectEntity::getId, subSql));
  }

  @Override
  public List<ProjectEntity> laborListForExecution(ProjectQueryForDemander projectQuery,
      Long userId) {
    final String subSql = SqlUtil.formatSql(" select project_id from t_project_labor "
        + "where labor_Id='{}' and status='1'  ", userId);
    return list(effectQuery()
        .gt(ProjectEntity::getStatus, ProjectStatusEnum.CREATE)
        .and(queryWrapper ->
            queryWrapper.eq(ProjectEntity::getProjectLeader, userId)
                .or()
                .inSql(ProjectEntity::getId, subSql))
    );
  }

  private LambdaQueryWrapper<ProjectEntity> effectQuery() {
    return new LambdaQueryWrapper<>();
  }
}
